技巧31 干净地“杀死”容器

如果一个容器终结时它的状态对用户来说很重要,那么用户可能需要搞清楚 dockerkilldockerstop 之间的区别。这一差异在需要应用正常关闭来保存数据的时显得尤为重要。

问题

想要干净地终结一个容器。

解决方案

使用 dockerstop 而不是 dockerkill 来干净地终结容器。要理解的关键点在于 dockerkill 的行为表现的和标准的命令行程序 kill 是不一样的。除非另有说明,一般执行 kill 程序时它会给指定的进程发送一个 TERM (也就是信号值15)信号。该信号指示程序应该终结,但是它不会强制要求程序退出。大多数程序在收到该信号时会执行某些清理任务,但是该程序也可以执行它自己喜欢的操作,包括忽略该信号。

相反, KILL 信号(也就是信号值9)会强制终止指定的程序。

令人不解的是, docker kill 会针对正在运行的容器发送一个 KILL 信号,让容器里的进程没有机会处理终止过程。这意味着它可能会将一些杂乱的文件(比如包含正在运行的进程ID的文件)遗留在文件系统里。视应用程序管理状态的能力而定,当用户再次启动该容器时可能会有问题,也可能不会。而更令人困惑的是, docker stop 命令的行为类似于标准的 kill 命令,它会发送一个 TERM 信号(见表5-1),不同的是它将会等待10秒,然后在容器未停止的情况下再发送 KILL 信号。

表5-1 停止和杀死容器
命 令 默认信号 默认信号值
kill TERM 15
docker kill KILL 9
docker stop TERM 15

总而言之,不要像使用 kill 那样使用 dockerkill ,最好养成使用 dockerstop 的习惯。

讨论

尽管在日常使用时我们推荐使用 dockerstop ,但是 dockerkill 具备一些额外的可配置能力,这使得用户可以通过 --signal 参数选择给容器发送的信号。如上所述,它的默认值是 KILL ,但是用户也可以发送 TERM 或一个不常见的Unix信号。

如果用户要编写自己的应用程序,并且想要跑在容器里,那可能会对 USR1 信号感兴趣。它是一个明确保留给应用程序来执行所需的任何操作,在某些地方它用作打印进度信息或类似信息的指示——用户可以将它用于自己认为合适的任何地方。 HUP 是另一种流行的方式,通常被服务器和其他常驻应用解读为触发配置文件的重新加载和“软”重启。当然,在开始发送随机信号前,请确保事先已经翻阅了正在运行的应用程序的文档!

results matching ""

    No results matching ""